package cn.liangxxhu.rocketmq.config;

import cn.liangxxhu.rocketmq.core.FailedMessageDao;
import cn.liangxxhu.rocketmq.core.strategy.DelayMessageStrategy;
import cn.liangxxhu.rocketmq.core.strategy.MessageSendStrategy;
import cn.liangxxhu.rocketmq.core.strategy.MessageSendStrategyFactory;
import cn.liangxxhu.rocketmq.core.strategy.NormalMessageStrategy;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

/**
 * RocketMQ 相关 Bean 的自动装配。
 *
 * 说明：类级别使用 @ConditionalOnMissingBean({RocketMQTemplate.class, JdbcTemplate.class})
 * 表示当容器中两者都不存在时才生效；具体 Bean 也分别通过 @ConditionalOnMissingBean 做兜底注册，
 * 方便业务侧自定义覆盖。
 */
@ConditionalOnMissingBean({RocketMQTemplate.class, JdbcTemplate.class})
public class RocketMQAutoConfiguration {

    /**
     * 延迟消息发送策略。
     * 当容器中不存在 {@link MessageSendStrategy} 的其他实现时，注册该策略。
     */
    @Bean
    @ConditionalOnMissingBean(MessageSendStrategy.class)
    public MessageSendStrategy delayMessageStrategy(RocketMQTemplate rocketMQTemplate) {
        return new DelayMessageStrategy(rocketMQTemplate);
    }

    /**
     * 普通（非延迟）消息发送策略。
     * 当容器中不存在同名 Bean 时注册。
     */
    @Bean
    @ConditionalOnMissingBean(NormalMessageStrategy.class)
    public NormalMessageStrategy normalMessageStrateg(RocketMQTemplate rocketMQTemplate) {
        return new NormalMessageStrategy(rocketMQTemplate);
    }

    /**
     * 消息发送策略工厂，用于按消息类型选择具体策略。
     */
    @Bean
    @ConditionalOnMissingBean(MessageSendStrategyFactory.class)
    public MessageSendStrategyFactory messageSendStrategyFactory(List<MessageSendStrategy> strategyList) {
        return new MessageSendStrategyFactory(strategyList);
    }

    /**
     * 失败消息持久化 DAO。
     */
    @Bean
    @ConditionalOnMissingBean(FailedMessageDao.class)
    public FailedMessageDao failedMessageDao(JdbcTemplate jdbcTemplate) {
        return new FailedMessageDao(jdbcTemplate);
    }
}
